/*
 * 文件名：ProtocalLTEDataDecode.java
 * 版权：亚信科技(南京)版权所有
 * 描述：TODO
 * 修改人：napo
 * 修改时间：2015-12-14
 * 修改内容：TODO
 */
package com.ailk.bigdata.etl.realstream.server.protocal.sdtp.netty.handler;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder;

import com.ailk.bigdata.etl.common.server.net.NettyUtil;
import com.ailk.bigdata.etl.realstream.server.constant.ProtocalSdtpConstant;
import com.ailk.bigdata.etl.realstream.server.model.Header;
import com.ailk.bigdata.etl.realstream.server.model.LTENetPackage;
import com.ailk.bigdata.etl.realstream.server.model.LTEPublic;
import com.ailk.bigdata.etl.realstream.server.model.MessageType;
import com.google.common.primitives.UnsignedInteger;

/**
 * @description TODO
 * @author [napo]
 * @version [版本号,2015-12-14]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ProtocalLTEDataDecode extends ReplayingDecoder<LTENetPackage>
{

	private static Logger logger = LoggerFactory.getLogger(ProtocalLTEDataDecode.class);

	private static final String defaultVal = "f";

	/**
	 * @see io.netty.handler.codec.ByteToMessageDecoder#decode(io.netty.channel.ChannelHandlerContext,
	 *      io.netty.buffer.ByteBuf, java.util.List)
	 */
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> message) throws Exception
	{
		// 解包
		byteBuf.markReaderIndex();

		int totalLength = byteBuf.readUnsignedShort() - 9;// 2
		int messageType = byteBuf.readUnsignedShort();// 2
		UnsignedInteger sequenceId = UnsignedInteger.valueOf(byteBuf.readUnsignedInt());// 4
		short totalContents = byteBuf.readUnsignedByte();// 1

		Header header = new Header();
		header.setTotalLength(totalLength);
		header.setMessageType(messageType);
		header.setSequenceId(sequenceId);
		header.setTotalContents(totalContents);

		LTENetPackage pack = new LTENetPackage();

		if (messageType == MessageType.notifyXDRData_Req.getValue())
		{

			LTEPublic publi = new LTEPublic();

			int length = byteBuf.readUnsignedShort();
			totalLength = totalLength - 54;
			publi.setLength(length);

			byte[] cbite = byteBuf.readBytes(2).array();
			String cbiteS = toTbcdHexString(cbite);
			publi.setCity(StringUtils.substringBefore(cbiteS, "f"));

			int inter = byteBuf.readUnsignedByte();
			publi.setInter(inter);

			byteBuf.readBytes(8);
			publi.setXdrId(Long.toString(byteBuf.readLong()));

			publi.setRat(byteBuf.readUnsignedByte());

			byte[] imsbite = byteBuf.readBytes(8).array();
			String imsbiteS = toTbcdHexString(imsbite);
			publi.setImsi(StringUtils.substringBefore(imsbiteS, defaultVal));

			byte[] imebite = byteBuf.readBytes(8).array();
			String imebiteS = toTbcdHexString(imebite);
			publi.setImei(StringUtils.substringBefore(imebiteS, defaultVal));

			byte[] msbite = byteBuf.readBytes(16).array();
			String msbiteS = toTbcdHexString(msbite);
			publi.setMsisdn(StringUtils.substringBefore(msbiteS, defaultVal));

			int dataType = ProtocalSdtpConstant.SDTP_LTE_DATA_TYPE_BASE * messageType + inter;

			pack.setDataType(dataType);
			pack.setLtePublic(publi);

			if (logger.isDebugEnabled())
			{
				logger.debug("字节码[" + Arrays.toString(cbite) + "]16进制码[" + toTbcdHexString(cbite) + "]bites[" + bytesToBits(cbite) + "]");
				logger.debug("字节码[" + Arrays.toString(imsbite) + "]16进制码[" + toTbcdHexString(imsbite) + "]bites[" + bytesToBits(imsbite) + "]");
				logger.debug("字节码[" + Arrays.toString(imebite) + "]16进制码[" + toTbcdHexString(imebite) + "]bites[" + bytesToBits(imebite) + "]");
				logger.debug("字节码[" + Arrays.toString(msbite) + "]16进制码[" + toTbcdHexString(msbite) + "]bites[" + bytesToBits(msbite) + "]");
			}

			cbite = null;
			imsbite = null;
			imebite = null;
			msbite = null;

			cbiteS = null;
			imsbiteS = null;
			imebiteS = null;
			msbiteS = null;

		}

		ByteBuf dataContent = byteBuf.readBytes(totalLength);

		pack.setHeader(header);
		pack.setDataContent(dataContent);

		message.add(pack);

		if (logger.isDebugEnabled())
		{
			logger.debug("服务端接收到一条来自客户端[{}]的消息,消息类型是[{}],包长[{}]", NettyUtil.getClientAdd(ctx), messageType, totalLength);
		}

	}

	/**
	 * @description TODO
	 * @param bytes
	 * @return
	 */
	public static String toTbcdHexString(byte[] bytes)
	{
		StringBuffer buffer = new StringBuffer(bytes.length);
		for (int i = 0; i < bytes.length; i++)
		{
			buffer.append(toHex(bytes[i]));
		}
		return buffer.toString();
	}

	/**
	 * @description TODO
	 * @param b
	 * @return
	 */
	public static String toHex(byte b)
	{
		String hex = Integer.toHexString(b & 0xFF);
		if (hex.length() == 1)
		{
			hex = '0' + hex;
		}
		return new String(reverse(hex));
	}

	/**
	 * @description TODO
	 * @param str
	 * @return
	 */
	public static String reverse(String str)
	{
		int len = str.length();
		StringBuffer sb = new StringBuffer(len);
		for (int i = (len - 1); i >= 0; i--)
		{
			sb.append(str.charAt(i));
		}
		return sb.toString();
	}

	/**
	 * byte[]转换成bit
	 * 
	 * @param b
	 * @return
	 */
	public static String bytesToBits(byte[] bytes)
	{
		StringBuffer sb = new StringBuffer();
		for (byte b : bytes)
		{
			sb.append(byteToBits(b));
		}
		return sb.toString();
	}

	/**
	 * byte转换成8位bit
	 * 
	 * @param b
	 * @return
	 */
	public static String byteToBits(byte b)
	{
		int z = b;
		z |= 256;
		String str = Integer.toBinaryString(z);
		int len = str.length();
		return str.substring(len - 8, len);
	}

	public static void main(String[] args)
	{
		byte[] bytes = new byte[] { 1, -16 };
		System.out.println(bytesToBits(bytes));
		System.out.println(toTbcdHexString(bytes));
	}
}
